<?php

namespace app\admin\controller\auth;

use ba\Random;
use Throwable;
use think\facade\Db;
use app\common\controller\Backend;
use app\common\controller\PCBase;
use app\admin\model\Admin as AdminModel;

class Admin extends PCBase
{
    /**
     * 模型
     * @var object
     * @phpstan-var AdminModel
     */
    protected object $model;

    protected array|string $preExcludeFields = ['create_time', 'update_time', 'password', 'salt', 'login_failure', 'last_login_time', 'last_login_ip'];

    protected array|string $quickSearchField = ['username', 'nickname'];


    protected array $withJoinTable = [];

    /**
     * 关联查询JOIN方式
     * @var string
     */
    protected string $withJoinType = 'LEFT';


    /**
     * 开启数据限制
     */
    protected string|int|bool $dataLimit = 'allAuthAndOthers';

    protected string $dataLimitField = 'id';

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new AdminModel();
    }

    /**
     * 查看
     * @throws Throwable
     */
    public function index()
    {
        $params      = $this->request->post();
        $username    = getIsset($params,'username');
        $nickname    = getIsset($params,'nickname');
        $mobile      = getIsset($params,'mobile');
        $status      = getIsset($params,'status');
        $create_time = getIsset($params,'create_time');
        $limit       = $params['limit']??10;
        $where       = [];

        if($status=='0'){
            $where[] = ['status','=',0];
        }

        if($status=='1'){
            $where[] = ['status','=',1];
        }

        if($username){
            $where[] = ['username', 'like', '%' . $username . '%'];
        }

        if($nickname){
            $where[] = ['nickname', 'like', '%' . $nickname . '%'];
        }

        if($mobile){
            $where[] = ['mobile', 'like', '%' . $mobile . '%'];
        }


        if ($create_time) {
            $createtimeArr = explode(',', $create_time);
            $where[] = ['create_time', '>=', strtotime($createtimeArr[0])];
            $where[] = ['create_time', '<=', strtotime($createtimeArr[1])];
        }



        $res = $this->model
            ->where($where)
            ->order('create_time desc')
            ->paginate($limit);

        $data = [
            'list'   => $res->items(),
            'total'  => $res->total(),
        ];
        return $this->jsonMessage(200, true, '获取成功', $data);
    }

    /**
     * 添加
     * @throws Throwable
     */
    public function add()
    {
        if ($this->request->isPost()){
            $data = $this->request->post();
            if (!$data) {
                return json(DefaultResponse(201, false, '参数不能为空!', null));
            }


            /**
             * 由于有密码字段-对方法进行重写
             * 数据验证
             */
            if ($this->modelValidate){
                try {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    $validate = new $validate;
                    $validate->scene('add')->check($data);
                } catch (Throwable $e) {
                    return json(DefaultResponse(201, false, $e->getMessage(), null));
                }
            }

            $mobile = $data['mobile']??[];
            if(!$mobile)  return json(DefaultResponse(201, false, '手机号不能为空!', null));
            $avatar = $data['avatar']??'';
            if(!$avatar)  $data['avatar'] = '/storage/default/20240531/20240531_20240557a98e05c62d27ca9144741b67e76150d409df92.jpg';


            $salt   = Random::build('alnum', 16);
            $passwd = $data['password']??'123456';
            $passwd = encrypt_password($passwd, $salt);

            $data   = $this->excludeFields($data);
            $result = false;
            if ($data['group_arr']) $this->checkGroupAuth($data['group_arr']);
            $this->model->startTrans();
            try {
                $data['salt']     = $salt;
                $data['password'] = $passwd;
                $result           = $this->model->save($data);
                if ($data['group_arr']) {
                    $groupAccess = [];
                    foreach ($data['group_arr'] as $datum) {
                        $groupAccess[] = [
                            'uid'      => $this->model->id,
                            'group_id' => $datum,
                        ];
                    }
                    Db::name('admin_group_access')->insertAll($groupAccess);
                }
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                return json(DefaultResponse(201, false, $e->getMessage(), null));
            }
            if ($result !== false) {
                return json(DefaultResponse(200, true, '操作成功!', null));
            } else {
                return json(DefaultResponse(201, false, '添加失败!', null));
            }
        }
        return json(DefaultResponse(201, false, '参数错误!', null));
    }

    /**
     * 编辑
     * @throws Throwable
     */
    public function edit($id = null)
    {
        $row = $this->model->find($id);
        if (!$row) {
            return json(DefaultResponse(201, false, '记录不能为空!', null));
        }

        $dataLimitAdminIds = $this->getDataLimitAdminIds();
        if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {
            return json(DefaultResponse(201, false, '你没有该权限!', null));
        }

        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                return json(DefaultResponse(201, false, '参数不能为空!', null));
            }

            /**
             * 由于有密码字段-对方法进行重写
             * 数据验证
             */
            if ($this->modelValidate) {
                try {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    $validate = new $validate;
                    $validate->scene('edit')->check($data);
                } catch (Throwable $e) {
                    return json(DefaultResponse(201, false, $e->getMessage(), null));
                }
            }

            if ($this->getAdminId() == $data['id'] && $data['status'] == '0') {
                return json(DefaultResponse(201, false, '请使用其他管理员帐户禁用当前帐户', null));
            }

            if (isset($data['password']) && $data['password']) {
                $this->model->resetPassword($data['id'], $data['password']);
            }

            $groupAccess = [];
            if ($data['group_arr']) {
                $checkGroups = [];
                foreach ($data['group_arr'] as $datum) {
                    if (!in_array($datum, $row->group_arr)) {
                        $checkGroups[] = $datum;
                    }
                    $groupAccess[] = [
                        'uid'      => $id,
                        'group_id' => $datum,
                    ];
                }
                $this->checkGroupAuth($checkGroups);
            }

            Db::name('admin_group_access')
                ->where('uid', $id)
                ->delete();

            $data   = $this->excludeFields($data);
            $result = false;
            $this->model->startTrans();
            try {
                $result = $row->save($data);
                if ($groupAccess) Db::name('admin_group_access')->insertAll($groupAccess);
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                return json(DefaultResponse(201, false, $e->getMessage(), null));
            }
            if ($result !== false) {
                return json(DefaultResponse(200, true, '更新成功!', null));
            } else {
                return json(DefaultResponse(201, false, '更新失败!', null));
            }
        }

        unset($row['salt'], $row['login_failure']);
        $row['password'] = '';
        return json(DefaultResponse(200, true, '获取成功', ['row'=>$row]));
    }

    /**
     * 删除
     * @param null $ids
     * @throws Throwable
     */
    public function del($ids = null)
    {

        $data = $this->request->post();
        if (!$data||!$ids){
            return  json(DefaultResponse(201, false, '参数错误', null));
        }


        $dataLimitAdminIds = $this->getDataLimitAdminIds();
        if ($dataLimitAdminIds) {
            $this->model->where($this->dataLimitField, 'in', $dataLimitAdminIds);
        }

        $pk    = $this->model->getPk();
        $data  = $this->model->where($pk, 'in', $ids)->select();
        $count = 0;
        $this->model->startTrans();
        try {
            foreach ($data as $v) {
                if ($v->id != $this->getAdminId()) {
                    $count += $v->delete();
                    Db::name('admin_group_access')
                        ->where('uid', $v['id'])
                        ->delete();
                }
            }
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            return   json(DefaultResponse(201, false, $e->getMessage(), null));
        }
        if ($count) {
            return   json(DefaultResponse(200, true, '操作成功', null));
        } else {
            return   json(DefaultResponse(201, false, '操作失败', null));
        }
    }

    /**
     * 检查分组权限
     * @throws Throwable
     */
    public function checkGroupAuth(array $groups)
    {
        if ($this->isSuperAdmin($this->getAdminId())) {
            return;
        }
        $authGroups = $this->getAllAuthGroups('allAuthAndOthers');
        foreach ($groups as $group) {
            if (!in_array($group, $authGroups)) {
                return json(DefaultResponse(201, false, '您无权将管理员添加到此组!', null));
            }
        }
    }



}